<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>新闻管理 - 后台管理</title>
  <link rel="stylesheet" href="/static/base.css">
  <link rel="stylesheet" href="/static/components.css">
  <link rel="stylesheet" href="/static/pages.css">
  <link rel="stylesheet" href="/static/admin/admin.css">
</head>
<body>
  <div class="admin-layout">
    <!-- 顶部导航 -->
    <div class="admin-header">
      <h2>新闻管理</h2>
      <div>
        <button class="btn" onclick="location.href='/'">返回前台</button>
        <button class="btn" onclick="logout()">退出</button>
      </div>
    </div>

    <!-- 主体内容 -->
    <div class="admin-main">
      <!-- 左侧导航（公共组件注入） -->
      <div class="admin-sidebar"></div>

      <!-- 右侧内容区域 -->
      <div class="admin-content">
        <div class="content-page active">
          <!-- 操作栏 -->
          <div class="action-bar">
            <div class="action-group">
              <button class="btn btn-primary" onclick="crawlNews(event)">
                <span class="btn-icon">🔄</span>
                爬取新闻
              </button>

              <button class="btn btn-info" onclick="crawlAll(event)">
                <span class="btn-icon">🚀</span>
                爬取全部
              </button>
              <button class="btn btn-warning" onclick="cleanupOldNews()">
                <span class="btn-icon">🗑️</span>
                清理旧数据
              </button>
            </div>
            <div class="search-group">
              <input type="text" id="searchInput" placeholder="搜索新闻标题..." class="search-input">
              <select id="categoryFilter" class="filter-select">
                <option value="">全部分类</option>
                <option value="业绩预告">业绩预告</option>
                <option value="资产重组">资产重组</option>
                <option value="A股">A股</option>
              </select>
              <button class="btn" onclick="searchNews()">搜索</button>
            </div>
          </div>

          <!-- 定时爬取设置 -->
          <div class="schedule-bar">
            <div class="schedule-header">
              <h4>📅 定时爬取设置</h4>
              <button class="btn btn-sm btn-info" onclick="toggleSchedulePanel()">
                <span class="btn-icon">⚙️</span>
                设置
              </button>
            </div>
            <div class="schedule-panel" id="schedulePanel" style="display: none;">
              <div class="schedule-content">
                <div class="schedule-item">
                  <label>第一次爬取时间:</label>
                  <input type="time" id="scheduleTime1" value="08:30:00" class="time-input">
                  <label class="checkbox-label">
                    <input type="checkbox" id="scheduleEnabled1" checked>
                    <span>启用</span>
                  </label>
                </div>
                <div class="schedule-item">
                  <label>第二次爬取时间:</label>
                  <input type="time" id="scheduleTime2" value="20:00:00" class="time-input">
                  <label class="checkbox-label">
                    <input type="checkbox" id="scheduleEnabled2" checked>
                    <span>启用</span>
                  </label>
                </div>
                <div class="schedule-item">
                  <label>爬取内容:</label>
                  <div class="checkbox-group">
                    <label class="checkbox-label">
                      <input type="checkbox" id="crawlNews" checked>
                      <span>新闻数据</span>
                    </label>

                  </div>
                </div>
                <div class="schedule-actions">
                  <button class="btn btn-success" onclick="saveSchedule()">
                    <span class="btn-icon">💾</span>
                    保存设置
                  </button>
                  <button class="btn btn-secondary" onclick="loadSchedule()">
                    <span class="btn-icon">📋</span>
                    加载设置
                  </button>
                </div>
              </div>
              <div class="schedule-status">
                <div class="status-item">
                  <span class="status-label">定时任务状态:</span>
                  <span id="scheduleStatus" class="status-value">运行中</span>
                </div>
                <div class="status-item">
                  <span class="status-label">下次爬取时间:</span>
                  <span id="nextCrawlTime" class="status-value">-</span>
                </div>
                <div class="status-item">
                  <span class="status-label">爬取内容:</span>
                  <span id="crawlContent" class="status-value">新闻数据</span>
                </div>
              </div>
            </div>
          </div>

          <!-- 统计信息 -->
          <div class="stats-bar">
            <div class="stat-item">
              <span class="stat-label">总新闻数</span>
              <span id="totalCount" class="stat-value">-</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">今日新增</span>
              <span id="todayCount" class="stat-value">-</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">本周新增</span>
              <span id="weekCount" class="stat-value">-</span>
            </div>
          </div>

          <!-- 新闻列表 -->
          <div class="table-container">
            <table class="news-table">
              <thead>
                <tr>
                  <th width="50">
                    <input type="checkbox" id="selectAll" onchange="toggleSelectAll()">
                  </th>
                  <th width="300">标题</th>
                  <th width="100">分类</th>
                  <th width="100">来源</th>
                  <th width="120">发布时间</th>
                  <th width="120">爬取时间</th>
                  <th width="100">相关股票</th>
                  <th width="60">操作</th>
                </tr>
              </thead>
              <tbody id="newsTableBody">
                <!-- 新闻数据将通过JavaScript动态加载 -->
              </tbody>
            </table>
          </div>

          <!-- 分页 -->
          <div class="pagination">
            <button class="btn" onclick="changePage(-1)" id="prevBtn">上一页</button>
            <span id="pageInfo">第 1 页，共 1 页</span>
            <button class="btn" onclick="changePage(1)" id="nextBtn">下一页</button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- 新闻详情模态框 -->
  <div id="newsDetailModal" class="modal">
    <div class="modal-content">
      <div class="modal-header">
        <h3>新闻详情</h3>
        <span class="close" onclick="closeNewsDetail()">&times;</span>
      </div>
      <div class="modal-body" id="newsDetailContent">
        <!-- 新闻详情内容 -->
      </div>
    </div>
  </div>

  <script src="/static/admin/components/sidebar.js"></script>
  <script>
    // 全局变量
    let currentPage = 1;
    let pageSize = 20;
    let totalPages = 1;
    let newsData = [];

    // 页面加载时初始化
    document.addEventListener('DOMContentLoaded', function() {
      loadNewsList();
      updateStats();
      loadSchedule();
      updateScheduleStatus();
      injectAdminSidebar('/admin/news');
      
      // 绑定分类筛选事件
      document.getElementById('categoryFilter').addEventListener('change', function() {
        currentPage = 1;
        totalPages = 1;
        loadNewsList();
      });
      
      // 定时更新状态
      setInterval(updateScheduleStatus, 30000); // 每30秒更新一次状态
    });

    // 加载新闻列表
    async function loadNewsList() {
      try {
        // 显示加载状态
        const tbody = document.getElementById('newsTableBody');
        tbody.innerHTML = '<tr><td colspan="7" class="loading">加载中...</td></tr>';
        
        const searchTerm = document.getElementById('searchInput').value;
        const category = document.getElementById('categoryFilter').value;
        
        let url = `/api/news/list?limit=${pageSize}&page=${currentPage}`;
        if (searchTerm) {
          url += `&search=${encodeURIComponent(searchTerm)}`;
        }
        if (category) {
          url += `&category=${encodeURIComponent(category)}`;
        }

        const response = await fetch(url);
        const result = await response.json();

        if (result.success) {
          newsData = result.data.news_list || [];
          totalPages = result.data.total_pages || 1;
          renderNewsTable();
          updatePagination();
        } else {
          showMessage('加载新闻列表失败: ' + result.error, 'error');
          tbody.innerHTML = '<tr><td colspan="7" class="no-data">加载失败</td></tr>';
        }
      } catch (error) {
        showMessage('加载新闻列表失败: ' + error.message, 'error');
        const tbody = document.getElementById('newsTableBody');
        tbody.innerHTML = '<tr><td colspan="7" class="no-data">加载失败</td></tr>';
      }
    }

    // 渲染新闻表格
    function renderNewsTable() {
      const tbody = document.getElementById('newsTableBody');
      tbody.innerHTML = '';

      if (newsData.length === 0) {
        tbody.innerHTML = '<tr><td colspan="7" class="no-data">暂无新闻数据</td></tr>';
        return;
      }

      newsData.forEach((news, index) => {
        const row = document.createElement('tr');
        row.innerHTML = `
          <td><input type="checkbox" class="news-checkbox" value="${news.id}"></td>
          <td class="news-title" title="${news.title}">
            <div class="title-text clickable-title" onclick="viewNewsDetail('${news.news_id}')">${news.title}</div>
            ${news.summary ? `<div class="summary-text">${news.summary.substring(0, 100)}...</div>` : ''}
          </td>
          <td><span class="category-badge">${news.category || '-'}</span></td>
          <td>${news.source || '-'}</td>
          <td>${formatDateTime(news.publish_time)}</td>
          <td>${formatDateTime(news.crawl_time)}</td>
          <td>${formatStockCodes(news.stock_codes)}</td>
          <td>
            <button class="btn btn-sm btn-danger" onclick="deleteNews(${news.id})">删除</button>
          </td>
        `;
        tbody.appendChild(row);
      });
    }

    // 更新分页信息
    function updatePagination() {
      const pageInfo = document.getElementById('pageInfo');
      const prevBtn = document.getElementById('prevBtn');
      const nextBtn = document.getElementById('nextBtn');

      // 确保页码有效
      if (totalPages < 1) totalPages = 1;
      if (currentPage < 1) currentPage = 1;
      if (currentPage > totalPages) currentPage = totalPages;

      pageInfo.textContent = `第 ${currentPage} 页，共 ${totalPages} 页`;
      prevBtn.disabled = currentPage <= 1;
      nextBtn.disabled = currentPage >= totalPages;
    }

    // 切换页面
    function changePage(delta) {
      const newPage = currentPage + delta;
      if (newPage >= 1 && newPage <= totalPages) {
        currentPage = newPage;
        loadNewsList();
      }
    }

    // 搜索新闻
    function searchNews() {
      const searchTerm = document.getElementById('searchInput').value.trim();
      if (searchTerm === '') {
        showMessage('请输入搜索关键词', 'warning');
        return;
      }
      
      currentPage = 1;
      totalPages = 1; // 重置总页数
      loadNewsList();
    }

    // 爬取新闻
    async function crawlNews(event) {
      const button = event.target;
      const originalText = button.innerHTML;
      
      try {
        button.innerHTML = '<span class="btn-icon">⏳</span>爬取中...';
        button.disabled = true;

        const response = await fetch('/api/news/crawl', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            tags: ['年报预期', '业绩预告', 'A股'],
            max_pages: 2
          })
        });

        const result = await response.json();

        if (result.success) {
          showMessage(`新闻爬取成功！获取 ${result.data.saved_count} 条新闻`, 'success');
          loadNewsList();
          updateStats();
        } else {
          showMessage('新闻爬取失败: ' + result.error, 'error');
        }
      } catch (error) {
        showMessage('新闻爬取失败: ' + error.message, 'error');
      } finally {
        button.innerHTML = originalText;
        button.disabled = false;
      }
    }

    


    // 爬取全部
    async function crawlAll(event) {
      const button = event.target;
      const originalText = button.innerHTML;
      
      try {
        button.innerHTML = '<span class="btn-icon">⏳</span>爬取中...';
        button.disabled = true;

        // 先爬取新闻
        const newsResponse = await fetch('/api/news/crawl', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            tags: ['年报预期', '业绩预告', 'A股'],
            max_pages: 2
          })
        });

        const newsResult = await newsResponse.json();
        let newsMessage = '';
        if (newsResult.success) {
          newsMessage = `新闻: ${newsResult.data.saved_count} 条`;
        } else {
          newsMessage = '新闻: 失败';
        }



        showMessage(`全部爬取完成！${newsMessage}`, 'success');
        loadNewsList();
        updateStats();
      } catch (error) {
        showMessage('全部爬取失败: ' + error.message, 'error');
      } finally {
        button.innerHTML = originalText;
        button.disabled = false;
      }
    }

    // 清理旧新闻
    async function cleanupOldNews() {
      if (!confirm('确定要清理30天前的旧新闻数据吗？此操作不可恢复！')) {
        return;
      }

      try {
        const response = await fetch('/api/news/cleanup', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            days: 30
          })
        });

        const result = await response.json();

        if (result.success) {
          showMessage(`清理完成！删除了 ${result.data.deleted_count} 条旧新闻`, 'success');
          loadNewsList();
          updateStats();
        } else {
          showMessage('清理失败: ' + result.error, 'error');
        }
      } catch (error) {
        showMessage('清理失败: ' + error.message, 'error');
      }
    }

    // 查看新闻详情
    async function viewNewsDetail(newsId) {
      try {
        const response = await fetch(`/api/news/detail/${newsId}`);
        const result = await response.json();

        if (result.success) {
          const news = result.data;
          const modal = document.getElementById('newsDetailModal');
          const content = document.getElementById('newsDetailContent');

          content.innerHTML = `
            <div class="news-detail">
              <div class="detail-header">
                <h4>${news.title}</h4>
                <div class="detail-meta">
                  <span>来源: ${news.source || '-'}</span>
                  <span>作者: ${news.author || '-'}</span>
                  <span>发布时间: ${formatDateTime(news.publish_time)}</span>
                  <span>分类: ${news.category || '-'}</span>
                </div>
              </div>
              <div class="detail-content">
                ${news.summary ? `<div class="summary"><strong>摘要:</strong> ${news.summary}</div>` : ''}
                ${news.content ? `<div class="content"><strong>正文:</strong> ${news.content}</div>` : ''}
                ${news.url ? `<div class="url"><strong>原文链接:</strong> <a href="${news.url}" target="_blank">${news.url}</a></div>` : ''}
              </div>
              ${news.stock_name ? `
                <div class="stock-info">
                  <h5>相关股票信息</h5>
                  <div class="stock-details">
                    <div>股票名称: ${news.stock_name}</div>
                    ${news.forecast_type ? `<div>预告类型: ${news.forecast_type}</div>` : ''}
                    ${news.forecast_indicator ? `<div>预告指标: ${news.forecast_indicator}</div>` : ''}
                    ${news.forecast_value ? `<div>预估值: ${news.forecast_value}</div>` : ''}
                    ${news.yoy_change ? `<div>同比变化: ${news.yoy_change}</div>` : ''}
                    ${news.change_reason ? `<div>变化原因: ${news.change_reason}</div>` : ''}
                  </div>
                </div>
              ` : ''}
            </div>
          `;

          modal.style.display = 'block';
        } else {
          showMessage('获取新闻详情失败: ' + result.error, 'error');
        }
      } catch (error) {
        showMessage('获取新闻详情失败: ' + error.message, 'error');
      }
    }

    // 关闭新闻详情模态框
    function closeNewsDetail() {
      document.getElementById('newsDetailModal').style.display = 'none';
    }

    // 删除新闻
    async function deleteNews(newsId) {
      if (!confirm('确定要删除这条新闻吗？此操作不可恢复！')) {
        return;
      }

      try {
        const response = await fetch(`/api/news/delete/${newsId}`, {
          method: 'DELETE'
        });

        const result = await response.json();

        if (result.success) {
          showMessage('新闻删除成功', 'success');
          loadNewsList();
          updateStats();
        } else {
          showMessage('删除失败: ' + result.error, 'error');
        }
      } catch (error) {
        showMessage('删除失败: ' + error.message, 'error');
      }
    }

    // 全选/取消全选
    function toggleSelectAll() {
      const selectAll = document.getElementById('selectAll');
      const checkboxes = document.querySelectorAll('.news-checkbox');
      
      checkboxes.forEach(checkbox => {
        checkbox.checked = selectAll.checked;
      });
    }

    // 批量删除
    async function batchDelete() {
      const checkboxes = document.querySelectorAll('.news-checkbox:checked');
      if (checkboxes.length === 0) {
        showMessage('请选择要删除的新闻', 'warning');
        return;
      }

      if (!confirm(`确定要删除选中的 ${checkboxes.length} 条新闻吗？此操作不可恢复！`)) {
        return;
      }

      const newsIds = Array.from(checkboxes).map(cb => cb.value);
      
      try {
        const response = await fetch('/api/news/batch-delete', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ news_ids: newsIds })
        });

        const result = await response.json();

        if (result.success) {
          showMessage(`批量删除成功！删除了 ${result.data.deleted_count} 条新闻`, 'success');
          document.getElementById('selectAll').checked = false;
          loadNewsList();
          updateStats();
        } else {
          showMessage('批量删除失败: ' + result.error, 'error');
        }
      } catch (error) {
        showMessage('批量删除失败: ' + error.message, 'error');
      }
    }

    // 更新统计信息
    async function updateStats() {
      try {
        const response = await fetch('/api/news/stats');
        const result = await response.json();

        if (result.success) {
          const stats = result.data;
          document.getElementById('totalCount').textContent = stats.total_count || 0;
          document.getElementById('todayCount').textContent = stats.today_count || 0;
          document.getElementById('weekCount').textContent = stats.week_count || 0;
        }
      } catch (error) {
        console.error('获取统计信息失败:', error);
      }
    }

    // 工具函数
    function formatDateTime(dateTimeStr) {
      if (!dateTimeStr) return '-';
      const date = new Date(dateTimeStr);
      return date.toLocaleDateString('zh-CN');
    }

    function formatStockCodes(stockCodes) {
      if (!stockCodes) return '-';
      try {
        const codes = JSON.parse(stockCodes);
        return Array.isArray(codes) ? codes.join(', ') : stockCodes;
      } catch {
        return stockCodes;
      }
    }

    function showMessage(message, type = 'info') {
      // 创建消息提示
      const messageDiv = document.createElement('div');
      messageDiv.className = `message message-${type}`;
      messageDiv.textContent = message;
      
      document.body.appendChild(messageDiv);
      
      // 3秒后自动移除
      setTimeout(() => {
        if (messageDiv.parentNode) {
          messageDiv.parentNode.removeChild(messageDiv);
        }
      }, 3000);
    }

    // 点击模态框外部关闭
    window.onclick = function(event) {
      const modal = document.getElementById('newsDetailModal');
      if (event.target === modal) {
        modal.style.display = 'none';
      }
    }

    // 回车键搜索
    document.getElementById('searchInput').addEventListener('keypress', function(e) {
      if (e.key === 'Enter') {
        searchNews();
      }
    });

    // 搜索输入框变化时自动搜索（防抖）
    let searchTimeout;
    document.getElementById('searchInput').addEventListener('input', function(e) {
      clearTimeout(searchTimeout);
      searchTimeout = setTimeout(() => {
        if (e.target.value.trim() === '') {
          // 如果搜索框为空，重新加载所有数据
          currentPage = 1;
          totalPages = 1;
          loadNewsList();
        }
      }, 500);
    });

    // 定时爬取相关函数
    function toggleSchedulePanel() {
      const panel = document.getElementById('schedulePanel');
      panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
    }

    // 保存定时设置
    async function saveSchedule() {
      const time1 = document.getElementById('scheduleTime1').value;
      const time2 = document.getElementById('scheduleTime2').value;
      const enabled1 = document.getElementById('scheduleEnabled1').checked;
      const enabled2 = document.getElementById('scheduleEnabled2').checked;
      const crawlNews = document.getElementById('crawlNews').checked;


      if (!time1 || !time2) {
        showMessage('请设置完整的爬取时间', 'warning');
        return;
      }

      if (!crawlNews) {
        showMessage('请选择爬取内容', 'warning');
        return;
      }

      try {
        const response = await fetch('/api/news/schedule', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            schedule_time1: time1,
            schedule_time2: time2,
            enabled1: enabled1,
            enabled2: enabled2,
            crawl_news: crawlNews,

          })
        });

        const result = await response.json();

        if (result.success) {
          showMessage('定时设置保存成功', 'success');
          updateScheduleStatus();
        } else {
          showMessage('保存失败: ' + result.error, 'error');
        }
      } catch (error) {
        showMessage('保存失败: ' + error.message, 'error');
      }
    }

    // 加载定时设置
    async function loadSchedule() {
      try {
        const response = await fetch('/api/news/schedule');
        const result = await response.json();

        if (result.success) {
          const schedule = result.data;
          document.getElementById('scheduleTime1').value = schedule.schedule_time1 || '08:30:00';
          document.getElementById('scheduleTime2').value = schedule.schedule_time2 || '20:00:00';
          document.getElementById('scheduleEnabled1').checked = schedule.enabled1 !== false;
          document.getElementById('scheduleEnabled2').checked = schedule.enabled2 !== false;
          document.getElementById('crawlNews').checked = schedule.crawl_news !== false;

          showMessage('定时设置加载成功', 'success');
        } else {
          showMessage('加载失败: ' + result.error, 'error');
        }
      } catch (error) {
        showMessage('加载失败: ' + error.message, 'error');
      }
    }

    // 更新定时状态
    async function updateScheduleStatus() {
      try {
        const response = await fetch('/api/news/schedule/status');
        const result = await response.json();

        if (result.success) {
          const status = result.data;
          document.getElementById('scheduleStatus').textContent = status.is_running ? '运行中' : '已停止';
          document.getElementById('scheduleStatus').className = status.is_running ? 'status-value running' : 'status-value stopped';
          document.getElementById('nextCrawlTime').textContent = status.next_crawl_time || '-';
          
          // 更新爬取内容显示
          const crawlNews = status.config.crawl_news;
          let contentText = '';
          if (crawlNews) {
            contentText = '新闻数据';
          } else {
            contentText = '已禁用';
          }
          document.getElementById('crawlContent').textContent = contentText;
        }
      } catch (error) {
        console.error('获取定时状态失败:', error);
      }
    }
  </script>

  <style>
    /* 新闻管理页面专用样式 */
    
    /* 操作栏样式 */
    .action-bar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 24px;
      padding: 20px;
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      border-radius: 12px;
      box-shadow: 0 2px 8px rgba(0,0,0,.05);
    }

    .action-group {
      display: flex;
      gap: 12px;
    }

    .search-group {
      display: flex;
      gap: 12px;
      align-items: center;
    }

    .search-input {
      padding: 10px 16px;
      border: 2px solid #e9ecef;
      border-radius: 8px;
      font-size: 14px;
      min-width: 250px;
      transition: all 0.3s ease;
    }

    .search-input:focus {
      outline: none;
      border-color: #667eea;
      box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
    }

    .filter-select {
      padding: 10px 16px;
      border: 2px solid #e9ecef;
      border-radius: 8px;
      font-size: 14px;
      background: white;
      cursor: pointer;
      transition: all 0.3s ease;
    }

    .filter-select:focus {
      outline: none;
      border-color: #667eea;
      box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
    }

    /* 统计栏样式 */
    .stats-bar {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 16px;
      margin-bottom: 24px;
    }

    .stat-item {
      background: linear-gradient(135deg, #ffffff, #f8f9fa);
      color: #2c3e50;
      padding: 20px;
      border-radius: 12px;
      text-align: center;
      box-shadow: 0 4px 12px rgba(0,0,0,0.08);
      transition: transform 0.3s ease;
      border: 1px solid #e9ecef;
    }

    .stat-item:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 20px rgba(0,0,0,0.12);
    }

    .stat-label {
      display: block;
      font-size: 14px;
      color: #6c757d;
      margin-bottom: 8px;
      font-weight: 500;
    }

    .stat-value {
      display: block;
      font-size: 28px;
      font-weight: 700;
      color: #2c3e50;
    }

    /* 定时爬取设置样式 */
    .schedule-bar {
      margin-bottom: 24px;
      background: linear-gradient(135deg, #e3f2fd, #bbdefb);
      border-radius: 12px;
      border: 1px solid #90caf9;
      overflow: hidden;
    }

    .schedule-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 16px 20px;
      background: linear-gradient(135deg, #1976d2, #1565c0);
      color: white;
    }

    .schedule-header h4 {
      margin: 0;
      font-size: 16px;
      font-weight: 600;
    }

    .schedule-panel {
      padding: 20px;
    }

    .schedule-content {
      display: grid;
      grid-template-columns: 1fr auto;
      gap: 20px;
      margin-bottom: 20px;
    }

    .schedule-item {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 12px;
      background: white;
      border-radius: 8px;
      border: 1px solid #e0e0e0;
    }

    .schedule-item label {
      font-weight: 500;
      color: #2c3e50;
      min-width: 120px;
    }

    .time-input {
      padding: 8px 12px;
      border: 2px solid #e9ecef;
      border-radius: 6px;
      font-size: 14px;
      transition: all 0.3s ease;
    }

    .time-input:focus {
      outline: none;
      border-color: #1976d2;
      box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
    }

    .checkbox-label {
      display: flex;
      align-items: center;
      gap: 6px;
      cursor: pointer;
      font-size: 14px;
      color: #495057;
    }

    .checkbox-label input[type="checkbox"] {
      width: 16px;
      height: 16px;
      cursor: pointer;
    }

    .checkbox-group {
      display: flex;
      gap: 20px;
      flex-wrap: wrap;
    }

    .schedule-actions {
      display: flex;
      gap: 12px;
      align-items: center;
    }

    .schedule-status {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 16px;
      padding: 16px;
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      border-radius: 8px;
      border: 1px solid #dee2e6;
    }

    .status-item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 8px 12px;
      background: white;
      border-radius: 6px;
      border-left: 3px solid #1976d2;
    }

    .status-label {
      font-weight: 500;
      color: #495057;
      font-size: 14px;
    }

    .status-value {
      font-weight: 600;
      font-size: 14px;
      padding: 4px 8px;
      border-radius: 4px;
    }

    .status-value.running {
      color: #28a745;
      background: rgba(40, 167, 69, 0.1);
    }

    .status-value.stopped {
      color: #dc3545;
      background: rgba(220, 53, 69, 0.1);
    }

    /* 新闻表格样式 */
    .news-table {
      width: 100%;
      border-collapse: collapse;
      background: white;
      border-radius: 12px;
      overflow: hidden;
      box-shadow: 0 4px 16px rgba(0,0,0,.08);
    }

    .news-table thead {
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      color: #495057;
    }

    .news-table th {
      padding: 16px 12px;
      text-align: left;
      font-weight: 600;
      font-size: 14px;
      border-bottom: 2px solid #dee2e6;
      color: #495057;
    }

    .news-table td {
      padding: 16px 12px;
      border-bottom: 1px solid #f8f9fa;
      vertical-align: top;
    }

    .news-table tbody tr {
      transition: all 0.3s ease;
    }

    .news-table tbody tr:hover {
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      transform: scale(1.01);
    }

    .news-table tbody tr:last-child td {
      border-bottom: none;
    }

    /* 新闻标题样式 */
    .news-title {
      max-width: 300px;
    }
    
    .title-text {
      font-weight: 700;
      color: #2c3e50;
      margin-bottom: 6px;
      line-height: 1.4;
      font-size: 15px;
      letter-spacing: 0.3px;
    }
    
    .clickable-title {
      cursor: pointer;
      transition: all 0.3s ease;
      padding: 4px 8px;
      border-radius: 6px;
      border: 2px solid transparent;
    }
    
    .clickable-title:hover {
      color: #667eea;
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      border-color: #667eea;
      transform: translateY(-1px);
      box-shadow: 0 2px 8px rgba(102, 126, 234, 0.2);
    }
    
    .summary-text {
      font-size: 12px;
      color: #6c757d;
      line-height: 1.4;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }

    /* 分类标签样式 */
    .category-badge {
      display: inline-block;
      padding: 4px 8px;
      background: linear-gradient(135deg, #28a745, #20c997);
      color: white;
      border-radius: 6px;
      font-size: 12px;
      font-weight: 500;
    }

    /* 操作按钮样式 */
    .btn-view {
      background: linear-gradient(135deg, #17a2b8, #138496);
      color: white;
      border: none;
      margin-right: 4px;
    }

    .btn-view:hover {
      background: linear-gradient(135deg, #138496, #117a8b);
      transform: translateY(-1px);
    }

    .btn-danger {
      background: linear-gradient(135deg, #dc3545, #c82333);
      color: white;
      border: none;
    }

    .btn-danger:hover {
      background: linear-gradient(135deg, #c82333, #bd2130);
      transform: translateY(-1px);
    }

    /* 分页样式 */
    .pagination {
      display: flex;
      justify-content: center;
      align-items: center;
      gap: 16px;
      margin-top: 24px;
      padding: 20px;
      background: #f8f9fa;
      border-radius: 12px;
    }

    .pagination .btn {
      padding: 10px 20px;
      border: 2px solid #e9ecef;
      background: white;
      color: #495057;
      border-radius: 8px;
      transition: all 0.3s ease;
    }

    .pagination .btn:hover:not(:disabled) {
      border-color: #667eea;
      color: #667eea;
      transform: translateY(-1px);
    }

    .pagination .btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
      background: #f8f9fa;
      color: #6c757d;
      border-color: #dee2e6;
    }

    #pageInfo {
      font-weight: 600;
      color: #495057;
    }

    /* 模态框样式 */
    .modal {
      display: none;
      position: fixed;
      z-index: 1000;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0,0,0,0.5);
      backdrop-filter: blur(4px);
    }

    .modal-content {
      background-color: white;
      margin: 2% auto;
      padding: 0;
      border-radius: 16px;
      width: 90%;
      max-width: 1000px;
      max-height: 90vh;
      overflow: hidden;
      box-shadow: 0 25px 50px rgba(0,0,0,0.25);
      animation: modalSlideIn 0.3s ease;
    }

    @keyframes modalSlideIn {
      from {
        opacity: 0;
        transform: translateY(-50px) scale(0.95);
      }
      to {
        opacity: 1;
        transform: translateY(0) scale(1);
      }
    }

    .modal-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 20px 24px;
      background: linear-gradient(135deg, #667eea, #764ba2);
      color: white;
      border-radius: 16px 16px 0 0;
    }

    .modal-header h3 {
      margin: 0;
      font-size: 20px;
      font-weight: 600;
      line-height: 1.3;
    }

    .close {
      color: white;
      font-size: 32px;
      font-weight: bold;
      cursor: pointer;
      transition: all 0.3s ease;
      width: 40px;
      height: 40px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      background: rgba(255,255,255,0.1);
    }

    .close:hover {
      transform: scale(1.1);
      background: rgba(255,255,255,0.2);
    }

    .modal-body {
      padding: 20px;
      max-height: 75vh;
      overflow-y: auto;
    }

    /* 新闻详情样式 */
    .news-detail {
      max-height: 75vh;
      overflow-y: auto;
    }
    
    .detail-header h4 {
      margin: 0 0 16px 0;
      color: #2c3e50;
      font-size: 22px;
      line-height: 1.4;
      font-weight: 700;
      border-bottom: 3px solid #667eea;
      padding-bottom: 10px;
    }
    
    .detail-meta {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 12px;
      font-size: 13px;
      color: #6c757d;
      margin-bottom: 20px;
      padding: 16px;
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      border-radius: 10px;
      border: 1px solid #dee2e6;
    }

    .detail-meta span {
      display: flex;
      align-items: center;
      padding: 6px 10px;
      background: white;
      border-radius: 6px;
      border-left: 3px solid #667eea;
      font-weight: 500;
    }
    
    .detail-content {
      margin-bottom: 20px;
    }
    
    .detail-content .summary,
    .detail-content .content {
      margin-bottom: 16px;
      line-height: 1.6;
      color: #495057;
      padding: 16px;
      background: #f8f9fa;
      border-radius: 10px;
      border-left: 3px solid #28a745;
    }

    .detail-content .summary strong,
    .detail-content .content strong {
      color: #2c3e50;
      font-weight: 600;
      display: block;
      margin-bottom: 6px;
      font-size: 15px;
    }
    
    .detail-content .url {
      padding: 12px;
      background: linear-gradient(135deg, #e3f2fd, #bbdefb);
      border-radius: 10px;
      border: 1px solid #90caf9;
    }

    .detail-content .url strong {
      color: #1976d2;
      font-weight: 600;
      display: block;
      margin-bottom: 6px;
    }
    
    .detail-content .url a {
      color: #1976d2;
      text-decoration: none;
      word-break: break-all;
      font-weight: 500;
      padding: 6px 10px;
      background: white;
      border-radius: 5px;
      display: inline-block;
      margin-top: 6px;
      border: 1px solid #90caf9;
    }

    .detail-content .url a:hover {
      text-decoration: none;
      background: #f5f5f5;
      transform: translateY(-1px);
      box-shadow: 0 2px 8px rgba(25, 118, 210, 0.2);
    }
    
    .stock-info {
      border-top: 2px solid #e9ecef;
      padding-top: 16px;
      margin-top: 16px;
    }
    
    .stock-info h5 {
      margin: 0 0 16px 0;
      color: #2c3e50;
      font-size: 18px;
      font-weight: 600;
      padding-bottom: 6px;
      border-bottom: 2px solid #667eea;
    }
    
    .stock-details {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
      gap: 12px;
      font-size: 13px;
      padding: 16px;
      background: linear-gradient(135deg, #f8f9fa, #e9ecef);
      border-radius: 10px;
      border: 1px solid #dee2e6;
    }

    .stock-details > div {
      padding: 10px 12px;
      background: white;
      border-radius: 6px;
      border-left: 3px solid #667eea;
      font-weight: 500;
      box-shadow: 0 2px 4px rgba(0,0,0,0.05);
      transition: transform 0.2s ease;
    }

    .stock-details > div:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    }
    
    /* 消息提示样式 */
    .message {
      position: fixed;
      top: 20px;
      right: 20px;
      padding: 16px 24px;
      border-radius: 8px;
      color: white;
      z-index: 1000;
      animation: slideIn 0.3s ease;
      box-shadow: 0 4px 12px rgba(0,0,0,0.15);
      font-weight: 500;
    }
    
    .message-success {
      background: linear-gradient(135deg, #28a745, #20c997);
    }
    
    .message-error {
      background: linear-gradient(135deg, #dc3545, #c82333);
    }
    
    .message-warning {
      background: linear-gradient(135deg, #ffc107, #e0a800);
      color: #333;
    }
    
    .message-info {
      background: linear-gradient(135deg, #17a2b8, #138496);
    }
    
    @keyframes slideIn {
      from {
        transform: translateX(100%);
        opacity: 0;
      }
      to {
        transform: translateX(0);
        opacity: 1;
      }
    }

    /* 无数据样式 */
    .no-data {
      text-align: center;
      padding: 40px;
      color: #6c757d;
      font-style: italic;
    }

    /* 加载状态样式 */
    .loading {
      text-align: center;
      padding: 40px;
      color: #667eea;
      font-weight: 500;
    }

    /* 响应式设计 */
    @media (max-width: 768px) {
      .action-bar {
        flex-direction: column;
        gap: 16px;
      }

      .search-group {
        width: 100%;
        flex-wrap: wrap;
      }

      .search-input {
        min-width: auto;
        flex: 1;
      }

      .stats-bar {
        grid-template-columns: 1fr;
      }

      .schedule-content {
        grid-template-columns: 1fr;
        gap: 12px;
      }

      .schedule-item {
        flex-direction: column;
        align-items: flex-start;
        gap: 8px;
      }

      .schedule-item label {
        min-width: auto;
      }

      .schedule-actions {
        flex-direction: column;
        gap: 8px;
      }

      .schedule-status {
        grid-template-columns: 1fr;
      }

      .news-table {
        font-size: 12px;
      }

      .news-table th,
      .news-table td {
        padding: 8px 6px;
      }

      .modal-content {
        width: 95%;
        margin: 10% auto;
      }

      .detail-meta {
        grid-template-columns: 1fr;
      }

      .stock-details {
        grid-template-columns: 1fr;
      }
    }
  </style>
</body>
</html>
